import { defineComponent, ref, PropType, markRaw, watch, nextTick } from 'vue'
import { VueFlow, useVueFlow, MarkerType, BezierEdge } from '@vue-flow/core'

import { Background } from '@vue-flow/background'
import { Controls } from '@vue-flow/controls'

import type {
  Node,
  Edge,
  NodeChange,
  NodeMouseEvent,
  EdgeChange,
  Connection,
} from '@vue-flow/core'
import type { Workflow } from '../types/workflow'

import '@vue-flow/core/dist/style.css'
import '@vue-flow/core/dist/theme-default.css'
import '@vue-flow/controls/dist/style.css'
import CustomNode from './CustomNode'
import NodeConfigModal from './NodeConfigModal'
import { debounce } from 'lodash-es'
import EnvConfigModal from './EnvConfigModal'
import { useWorkflowStore } from '../stores/workflow'
import StartNode from './StartNode'
import StartNodeConfigModal from './StartNodeConfigModal'

export default defineComponent({
  name: 'WorkflowEditor',
  props: {
    workflow: {
      type: Object as PropType<Workflow>,
      required: true,
    },
    onSave: {
      type: Function as PropType<(workflow: Workflow) => void>,
      required: true,
    },
  },
  setup(props) {
    const {
      addNodes,
      addEdges,
      getNodes,
      getEdges,
      getViewport,
      setViewport,
      removeNodes,
      removeEdges,
      onPaneReady,
    } = useVueFlow()

    const nodeTypes = [
      {
        type: 'start',
        title: '开始',
        color: '#9B6EFF',
        icon: 'i-mdi-play-circle',
      },
      {
        type: 'action',
        title: '运行脚本',
        color: '#4ECDC4',
        icon: 'i-mdi-script-text',
      },
      {
        type: 'internal',
        title: '内部调用',
        color: '#FF9F1C',
        icon: 'i-mdi-function',
      },
      {
        type: 'output',
        title: '显示结果',
        color: '#45B7D1',
        icon: 'i-mdi-text-box',
      },
    ]

    const setupPage = () => {
      // 清除现有节点和边
      removeEdges(getEdges.value.map(edge => edge.id))
      removeNodes(getNodes.value.map(node => node.id))

      // 添加新的节点和边
      const nodes = props.workflow.nodes.map(node => ({
        id: node.id,
        type: 'custom',
        position: node.position,
        data: {
          label: node.title,
          icon:
            nodeTypes.find(t => t.type === node.type)?.icon ||
            'i-mdi-help-circle',
          type: node.type,
          color: nodeTypes.find(t => t.type === node.type)?.color || '#666',
          config: node.config,
        },
      }))

      const edges = props.workflow.connections.map(conn => ({
        id: conn.id,
        source: conn.source,
        target: conn.target,
      }))

      addNodes(nodes)
      addEdges(edges)

      if (props.workflow.viewport) {
        setViewport(props.workflow.viewport)
      } else {
        setViewport({ x: 0, y: 0, zoom: 1.5 })
      }
    }

    onPaneReady(() => {
      setupPage()
    })

    // 监听 workflow 变化，更新节点和边
    watch(
      () => props.workflow,
      (v, old) => {
        if (v && (!old || old.id !== v.id)) {
          setupPage()
        }
      },
      { immediate: false }
    )

    const addNewNode = (
      type: string,
      title: string,
      color: string,
      position: { x: number; y: number }
    ) => {
      const newNode: Node = {
        id: `node-${Date.now()}`,
        type: type === 'start' ? 'start' : 'custom',
        position,
        data: {
          label: title,
          type,
          color,
          icon:
            nodeTypes.find(t => t.type === type)?.icon || 'i-mdi-help-circle',
          config: type === 'start' ? { params: [] } : {},
        },
      }
      addNodes([newNode])
    }

    // 注册自定义节点类型，使用 markRaw 包装组件
    const customNodeTypes = markRaw({
      custom: CustomNode,
      start: StartNode,
    })

    const edgeTypes = markRaw({
      bezier: BezierEdge,
    })

    // 事件处理函
    const handleNodesChange = (_: NodeChange[]) => {
      debouncedHandleSave()
    }

    const handleEdgesChange = (_: EdgeChange[]) => {
      debouncedHandleSave()
    }

    // 验证连接是否有效
    const isValidConnection = (connection: Connection): boolean => {
      const nodes = getNodes.value
      const sourceNode = nodes.find(node => node.id === connection.source)
      const targetNode = nodes.find(node => node.id === connection.target)

      if (!sourceNode || !targetNode) return false

      const sourceType = sourceNode.data.type
      const targetType = targetNode.data.type

      const validConnections: Record<string, string[]> = {
        start: ['action', 'internal', 'output'],
        action: ['action', 'internal', 'output'],
        internal: ['action', 'internal', 'output'],
        output: [],
      }

      return validConnections[sourceType]?.includes(targetType) || false
    }

    // 修改连接处理函数
    const handleConnect = (connection: Connection) => {
      if (!isValidConnection(connection)) {
        console.log('连接无效')
        return
      }

      const newEdge: Edge = {
        id: `edge-${Date.now()}`,
        source: connection.source,
        target: connection.target,
      }

      addEdges([newEdge])
    }

    const defaultEdgeOptions = {
      type: 'bezier',
      animated: false,
      //可选
      style: {
        strokeWidth: 2,
        stroke: '#B1B1B7',
      },
      markerEnd: {
        type: MarkerType.ArrowClosed,
        width: 16,
        height: 16,
        color: '#B1B1B7',
      },
    }

    // 添加选中节点的状态
    const selectedNode = ref<Node | null>(null)

    // 添加 modal 显示状态
    const showConfigModal = ref(false)

    // 修改节点点击处理函数
    const handleNodeClick = (event: NodeMouseEvent) => {
      selectedNode.value = event.node
      if (event.node.data.type === 'start') {
        showStartConfigModal.value = true
      } else {
        showConfigModal.value = true
      }
    }

    // 修改关闭 modal 的处理函数
    const handleCloseModal = () => {
      showConfigModal.value = false
    }

    const handleSaveModal = (cfg: Record<string, any>) => {
      if (selectedNode.value) {
        selectedNode.value.data.config = cfg
        handleSave(selectedNode.value)
      }

      handleCloseModal()
    }

    // 修改工作流保存处理函数
    const handleSave = (selNode?: Node) => {
      const nodes = getNodes.value
      const edges = getEdges.value

      const workflowData: Workflow = {
        ...props.workflow,
        nodes: nodes.map(node => ({
          id: node.id,
          type: node.data.type,
          title: node.data.label,
          position: node.position,
          config:
            selNode?.id === node.id ? selNode.data.config : node.data.config,
        })),
        viewport: {
          x: getViewport().x,
          y: getViewport().y,
          zoom: getViewport().zoom,
        },
        connections: edges.map(edge => ({
          id: edge.id,
          source: edge.source,
          target: edge.target,
        })),
      }

      props.onSave(workflowData)
    }

    const debouncedHandleSave = debounce(handleSave, 100)

    // 添加右键菜单状态
    const contextMenu = ref({
      show: false,
      x: 0,
      y: 0,
      position: { x: 10, y: 10 },
    })

    // 处理画布右键点击
    const handlePaneContextMenu = (event: MouseEvent) => {
      event.preventDefault()
      // 获取画布元素和其位置信息
      const flowWrapper = event.currentTarget as HTMLElement
      const rect = flowWrapper.getBoundingClientRect()

      // 计算相画布的坐标
      const position = {
        x: (event.clientX - rect.left) / getViewport().zoom - getViewport().x,
        y: (event.clientY - rect.top) / getViewport().zoom - getViewport().y,
      }

      contextMenu.value = {
        show: true,
        x: event.clientX,
        y: event.clientY,
        position, // 保存实际位置信息
      }
    }

    // 处理点击其他区域关闭菜单
    const handleClickOutside = () => {
      contextMenu.value.show = false
    }

    // 在 setup 函数中添加选中边的状态
    const selectedEdge = ref<Edge | null>(null)

    // 添加边点击处理函数
    const handleEdgeClick = (event: any) => {
      selectedEdge.value = event.edge
    }

    // 添加环境变量配置相关状态
    const showEnvModal = ref(false)
    const workflowStore = useWorkflowStore()

    // 添加环境变量配置处理函数
    const handleOpenEnvConfig = () => {
      showEnvModal.value = true
    }

    const handleSaveEnv = (env: Record<string, string>) => {
      workflowStore.updateWorkflowEnv(props.workflow.id, env)
      showEnvModal.value = false
    }

    // 添加开始节点配置相关状态
    const showStartConfigModal = ref(false)

    // 添加开始节点配置保存处理函数
    const handleSaveStartConfig = (config: any) => {
      if (selectedNode.value) {
        selectedNode.value.data.config = config
        handleSave(selectedNode.value)
      }
      showStartConfigModal.value = false
    }

    return () => (
      <div class="h-full bg-[#1A1A1A] relative">
        {/* 添加环境变量配置按钮 */}
        <div class="absolute top-4 right-4 z-10">
          <button
            onClick={handleOpenEnvConfig}
            class="px-4 py-2 bg-[#4D3A65] text-white rounded hover:bg-[#5D4A75] flex items-center gap-2"
          >
            <i class="i-mdi-cog text-xl" />
            环境变量
          </button>
        </div>

        <VueFlow
          default-viewport={{ x: 0, y: 0, zoom: 1.5 }}
          style={{ width: '100%', height: '100%' }}
          node-types={customNodeTypes}
          edge-types={edgeTypes}
          onNodesChange={handleNodesChange}
          onEdgesChange={handleEdgesChange}
          onConnect={handleConnect}
          connect-mode="loose"
          connection-radius={60}
          connection-line-options={defaultEdgeOptions}
          default-edge-options={defaultEdgeOptions}
          connection-line-type="simple-bezier"
          onNodeClick={handleNodeClick}
          onPaneContextMenu={handlePaneContextMenu}
          onClick={handleClickOutside}
          elementsSelectable={true}
          nodesDraggable={true}
          nodesConnectable={true}
          class="bg-[#1A1A1A]"
          edgesSelectable={true}
          onEdgeClick={handleEdgeClick}
          edgesFocusable={true}
          selectNodesOnDrag={true}
        >
          <Background pattern-color="#2D1A45" gap={16} />
          <Controls
            class="!bg-[#2D1A45] !border-[#3D2A55] !shadow-lg"
            showZoom={true}
            showFitView={true}
            showInteractive={true}
          />

          {/* 右键菜单 */}
          {contextMenu.value.show && (
            <div
              class="fixed z-50 w-64 bg-[#2D1A45] rounded-lg shadow-xl border border-[#3D2A55] overflow-hidden"
              style={{
                left: `${contextMenu.value.x}px`,
                top: `${contextMenu.value.y}px`,
              }}
            >
              <div class="py-1">
                {nodeTypes.map(node => (
                  <div
                    key={node.title}
                    class="px-4 py-2 hover:bg-[#4D3A65] cursor-pointer flex items-center space-x-3 text-white"
                    onClick={() => {
                      addNewNode(
                        node.type,
                        node.title,
                        node.color,
                        contextMenu.value.position // 使用保存的位置信息
                      )
                      contextMenu.value.show = false
                    }}
                  >
                    <i
                      class={`${node.icon} text-xl`}
                      style={{ color: node.color }}
                    />
                    <span class="text-sm">{node.title}</span>
                  </div>
                ))}
              </div>
            </div>
          )}
        </VueFlow>

        {/* Modal */}
        {showConfigModal.value && selectedNode.value && (
          <NodeConfigModal
            node={selectedNode.value}
            onClose={handleCloseModal}
            onSave={handleSaveModal}
          />
        )}

        {/* 环境变量配置 Modal */}
        {showEnvModal.value && (
          <EnvConfigModal
            env={props.workflow.env || {}}
            onClose={() => (showEnvModal.value = false)}
            onSave={handleSaveEnv}
          />
        )}

        {showStartConfigModal.value && selectedNode.value && (
          <StartNodeConfigModal
            node={selectedNode.value}
            onClose={() => (showStartConfigModal.value = false)}
            onSave={handleSaveStartConfig}
          />
        )}
      </div>
    )
  },
})
